package com.max.base;

import com.max.utils.CommonUtils;
import com.max.utils.ConnectionUtils;

import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.sql.*;
import java.util.ArrayList;
import java.util.List;

public abstract class BaseDao<T> {

    public abstract int insert(T entity);

    public abstract int updateById(T entity);

    public abstract int deleteById(Long id);

    public abstract T queryById(Long id);

    public abstract List<T> selectList(T entity);



    /**
     * 通用的数据操作方法
     *
     * @param sql  要执行的SQL
     * @param args SQL的参数
     * @return 影响的行数
     */
    public int actionExecute(String sql, Object[] args) {
        Connection connection = ConnectionUtils.getConnection();
        try {
            PreparedStatement preparedStatement = connection.prepareStatement(sql);
            setParamsHandle(preparedStatement, args);
            return preparedStatement.executeUpdate();
        } catch (SQLException e) {
            throw new RuntimeException(e);
        }
    }


    /**
     * 通用的数据查询方法
     *
     * @param clazz 要封装的类对象
     * @param sql   要执行的SQL
     * @param args  SQL的参数
     * @return 查询结果·
     */
    public List<T> queryExecute(Class<T> clazz, String sql, Object[] args) {
        Connection connection = ConnectionUtils.getConnection();
        try {
            //创建SQL预编译对象
            PreparedStatement preparedStatement = connection.prepareStatement(sql);
            setParamsHandle(preparedStatement, args);

            ResultSet resultSet = preparedStatement.executeQuery();
            List<T> resultList = new ArrayList<>();
            Field[] fields = clazz.getDeclaredFields();
            while (resultSet.next()) {
                T entity = clazz.getConstructor().newInstance();
                for (Field field : fields) {
                    CommonUtils.setFiledValue(entity, field, resultSet);
                }
                resultList.add(entity);
            }
            return resultList;
        } catch (SQLException | InvocationTargetException | InstantiationException | IllegalAccessException |
                 NoSuchMethodException e) {
            throw new RuntimeException(e);
        }
    }


    public void setParamsHandle(PreparedStatement preparedStatement, Object[] args) throws SQLException {
        int paramIndex = 1;
        for (Object arg : args) {
            if (CommonUtils.isNotBlank(arg)) {
                preparedStatement.setObject(paramIndex++, arg);
            }
        }
    }


}
